﻿cmake_minimum_required(VERSION 3.10)

include(config.cmake OPTIONAL)

#----------------------- 环境参数 ----------------------
set(PROJECT_ROOT ${CMAKE_CURRENT_LIST_DIR}/..)
file(RELATIVE_PATH PROJECT_ROOT_NAME ${PROJECT_ROOT}/.. ${PROJECT_ROOT})

if("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Windows")
	set(USERNAME $ENV{USERNAME})
else()
	set(USERNAME $ENV{USER})
endif()

#----------------------- 取默认参数宏 ----------------------
macro(set_default)
if("${${ARGV0}}" STREQUAL "")
	set(${ARGV0} $ENV{${ARGV0}})	
	if("${${ARGV0}}" STREQUAL "")	    
		set(${ARGV0} ${ARGV1} ${ARGV2} ${ARGV3} ${ARGV4} ${ARGV5} ${ARGV6})
	endif()
endif()
endmacro()

#----------------------- 配置参数 ----------------------
set_default(PROJECT_NAME ${PROJECT_ROOT_NAME})
set_default(MAJOR_VERSION 1)
set_default(MINOR_VERSION 0)
set_default(REVISION 0)
set_default(BUILD_NUMBER 1)
set_default(PROJECT_VERSION ${MAJOR_VERSION}.${MINOR_VERSION}.${REVISION}.${BUILD_NUMBER})
set_default(COMPANY_NAME ${USERNAME})
set_default(FILE_DESCRIPTION ${PROJECT_NAME})
set_default(LEGAL_COPYRIGHT "(C) ${COMPANY_NAME}. All rights reserved.")
set_default(PRODUCT_NAME ${PROJECT_NAME})
set_default(CMAKE_BUILD_TYPE Release)

set_default(SOURCE_GLOB ../src/*.c ../src/*.cpp *.c *.cpp) #源码
set_default(HEADER_GLOB ../src/*.h ../include/*.h *.h) #头文件
set_default(EXCLUDES CMakeFiles) #排除文件
set_default(LIBS ws2_32 user32) #链接库
set_default(CFLAGS -Wall -DUNICODE -D_UNICODE) #编译选项
set_default(LDFLAGS -static -municode) #链接选项


#----------------------- 查找所有源码文件和头文件 ----------------------
file(GLOB_RECURSE ALL_SOURCES ${SOURCE_GLOB}) 
file(GLOB_RECURSE ALL_HEADERS ${HEADER_GLOB})

#----------------------- 按EXLUDES变量过滤掉不需要编译的文件 ----------------------
set(EXCLUDES ${EXCLUDES} .*/CMakeFiles/.*) 
foreach(EXCL IN LISTS EXCLUDES) 
	list(FILTER ALL_SOURCES EXCLUDE REGEX ${EXCL})
	list(FILTER ALL_HEADERS EXCLUDE REGEX ${EXCL})
endforeach()

#----------------------- 将每个头文件所在目录添加到include ----------------------
foreach(FILENAME IN LISTS ALL_HEADERS)
	get_filename_component(DIRNAME ${FILENAME} DIRECTORY)	
	if(NOT "${DIRNAME}" IN_LIST INCS)
		list(APPEND INCS ${DIRNAME})		
	endif()
endforeach()
foreach(INC IN LISTS INCS)
	include_directories(${INC})
endforeach()
include_directories(${PROJECT_ROOT}/include)

#----------------------- 根据源码文件类型确定语言 ----------------------
set(HAS_C )
set(HAS_CXX )
foreach(FILENAME IN LISTS ALL_SOURCES)
	get_filename_component(EXTNAME ${FILENAME} EXT)	
	if(NOT ${EXTNAME} STREQUAL ".c")
		set(HAS_CXX CXX)
	else()
		set(HAS_C C)	
	endif()
endforeach()
project(${PROJECT_NAME} LANGUAGES ${HAS_C} ${HAS_CXX})


#-------------------- RC文件处理 --------------------
if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/resource.rc.in)
	file(RELATIVE_PATH RC_DEP_DIR "${CMAKE_BINARY_DIR}" "${CMAKE_CURRENT_LIST_DIR}")		
	set(ICON_FILE ${RC_DEP_DIR}/icon.ico)
	set(MANIFEST_FILE ${RC_DEP_DIR}/manifest.xml)
	set(RC_SOURCE_IN ${CMAKE_CURRENT_LIST_DIR}/resource.rc.in)
	set(RC_SOURCE ${CMAKE_BINARY_DIR}/resource.rc)
	set(RC_FLAGS "-D HAS_VERSION_INFO")
	if(EXISTS ${ICON_FILE})
		set(RC_FLAGS "${RC_FLAGS} -D HAS_ICON")
		set_source_files_properties(${RC_SOURCE} PROPERTIES OBJECT_DEPENDS ${ICON_FILE})
	endif()
	if(EXISTS ${MANIFEST_FILE})
		set(RC_FLAGS "${RC_FLAGS} -D HAS_MANIFEST")
		set_source_files_properties(${RC_SOURCE} PROPERTIES OBJECT_DEPENDS ${MANIFEST_FILE})
	endif()	
	configure_file("${RC_SOURCE_IN}" "${RC_SOURCE}")	
	set_source_files_properties(${RC_SOURCE} PROPERTIES OBJECT_DEPENDS ${RC_SOURCE_IN})
	get_filename_component(COMPILER_DIR ${CMAKE_C_COMPILER} DIRECTORY)
	set(CMAKE_RC_COMPILER ${COMPILER_DIR}/windres)	
	set(CMAKE_RC_FLAGS ${RC_FLAGS})
endif()



#----------------------- 其他编译参数设置 ----------------------

#导出compile_commands.json文件
set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE)


link_libraries(${LIBS})
link_libraries(${LDFLAGS})
add_compile_options(${CFLAGS})

if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
	
else()
	link_libraries(-s)
	link_libraries(-Wl,--subsystem,windows)
endif()

#-------------------- 编译主程序 --------------------
add_executable(${PROJECT_NAME} ${ALL_SOURCES} ${RC_SOURCE})


#-------------------- 链接assets资源文件 --------------------
if(EXISTS ${PROJECT_ROOT}/assets)
	file(COPY ${PROJECT_ROOT}/assets DESTINATION .)
	set(ASSETS_OPT  -Wl,--format=binary)
	set(ASSETS_FILES  )	
	file(GLOB_RECURSE RESS RELATIVE "${PROJECT_ROOT}/assets" "${PROJECT_ROOT}/assets/*" )
	foreach(F IN LISTS RESS)
		#message(${F})		
	    set(ASSETS_OPT ${ASSETS_OPT} -Wl,assets/${F})
		set(ASSETS_FILES  ${ASSETS_FILES} ${PROJECT_ROOT}/assets/${F})		
	endforeach()
	set(ASSETS_OPT ${ASSETS_OPT} -Wl,--format=default)	
	target_link_options(${PROJECT_NAME} PUBLIC ${ASSETS_OPT})
	set_target_properties(${PROJECT_NAME} PROPERTIES LINK_DEPENDS "${ASSETS_FILES}")
endif()

#-------------------- assets资源列表写入到头文件 --------------------
if(DEFINED RESS)
    file(MAKE_DIRECTORY "${PROJECT_ROOT}/include")
	set(ASSETS_SIM  "#pragma once\n")
	set(ASSETS_ITEM  "#define ASSETS_FILE_LIST {\\")
	foreach(F IN LISTS RESS)		
		string(REPLACE . _ SIM1 ${F})
		string(REPLACE / _ SIM ${SIM1})
		set(ASSETS_SIM  "${ASSETS_SIM}\nextern const unsigned char _binary_assets_${SIM}_start[];")
		set(ASSETS_SIM  "${ASSETS_SIM}\nextern const unsigned char _binary_assets_${SIM}_end[];")
		set(ASSETS_ITEM "${ASSETS_ITEM}\n    {\"${F}\", _binary_assets_${SIM}_start, _binary_assets_${SIM}_end},\\")
	endforeach()
	set(ASSETS_ITEM "${ASSETS_ITEM}\n}\n")
	set(ASSETS_SIM "${ASSETS_SIM}\n\n")	
	file(WRITE "${PROJECT_ROOT}/include/assets.h" "${ASSETS_SIM}")
	file(APPEND "${PROJECT_ROOT}/include/assets.h" "${ASSETS_ITEM}")
endif()



